<template>
  <div style="padding: 20px">
    <common-search v-bind="querySearch" v-model="queryParams" @search="search" v-model:searchClose="searchClose" v-show="showSearch"/>
    <el-row style="height: 50px">
      <el-col :span="20">
        <slot name="toolbar" v-bind="{topActions, _data, _table:_this, selection}">
          <common-action v-for="(action, ai) in topActions" v-bind="{...action, location:'top', _table:_this, selection, emptyData, ak: `top${ai}`}"
                         @add="handleAdd" @edit="handleEdit" @delete="handleDelete" @search="search" @importTemplate="handleImportTemplate"
                         @importData="handleImportData"
                         v-model:visible="actionsFormVisible[`top${ai}`]"/>
        </slot>
      </el-col>
      <el-col :span="4" align="right">
        <common-right-toolbar v-model:showSearch="showSearch" @queryTable="search" v-model:columns="columns" show-columns-type="checkbox"></common-right-toolbar>
      </el-col>
    </el-row>
    <div :style="contentHeight">
      <el-table :data="_data" @selectionChange="handleSelectionChange" v-bind="tableProps" class="tableBox" v-loading="loading" height="100%">
        <slot :data="_data">
          <template v-if="columns && columns.length">
            <template v-for="column in columns">
              <common-column v-bind="{column}"/>
            </template>
          </template>
          <template v-else>
            <el-table-column type="selection" width="55"/>
            <el-table-column type="index" label="序号" width="55"/>
            <el-table-column v-if="_data && _data.length" v-for="field in Object.keys(_data[0])"
                             :prop="field" :label="field" :width="computeColumnWidth(field)"/>
          </template>
          <el-table-column v-if="hideRowAction ? false : rowActions.length" label="操作" v-bind="rowActionColProp">
            <template #default="{row, $index}">
              <slot name="rowAction" v-bind="{rowActions, _data, _table:_this, row}">
                <common-action v-for="(action, ai) in rowActions" v-bind="{...action, location:'row', _table:_this, row, emptyData, ak: `row${$index}_${ai}`}"
                               @add="handleAdd" @edit="handleEdit" @delete="handleDelete" @search="search" @importTemplate="handleImportTemplate"
                               v-model:visible="actionsFormVisible[`row${$index}_${ai}`]"/>
              </slot>
            </template>
          </el-table-column>
        </slot>
      </el-table>
    </div>
    <el-pagination
        v-if="isPage"
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :page-sizes="pagination.pageSizes"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        style="margin-top: 8px;display: flex;height: 32px"
        :style="`justify-content: ${paginationJC};`"
        @sizeChange="search"
        @currentChange="search"
    />
  </div>
</template>
<script setup lang="ts">
import {commonHook} from "./hook/index.js"
import CommonSearch from "./CommonSearch.vue"
import {ref, computed, defineModel, defineProps, onMounted} from "vue";
import CommonAction from "./CommonAction.vue"
import CommonColumn from "./CommonColumn.vue";
import CommonRightToolbar from "./CommonRightToolbar.vue";

const showSearch = ref(true);

const columns = defineModel('columns',{
  type: Array<{show:Boolean,type:String}>,
  default: []
})

const props = defineProps({
  baseUrl: {
    type: String,
    default: '#'
  },
  simpleTitle: {
    type: String,
    default: '元素'
  },
  rowActionColProp: {
    type: Object,
    default: () => ({
      width: 210,
      fixed: 'right',
    })
  },
  hideRowAction: {
    type: Boolean,
    default: false
  },
  hideTopAction: {
    type: Boolean,
    default: false
  },
  tableProps: Object,
  querySearch: Object,
  actions: {
    type: Array<{location:string|undefined}>,
    default: () => ([
      {action: 'add', location: 'top'},
      {action: 'delete', location: 'top'},
      {action: 'detail', location: 'row'},
      {action: 'edit', location: 'row'},
      {action: 'delete', location: 'row'},
    ])
  },
  //分页配置
  isPage: {
    type: Boolean,
    default: true
  },
  //justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
  paginationJC: {
    type: String,
    default: 'flex-start'
  },
  //默认查询条件
  conditions: Array,
  isSub: {
    type: Boolean,
    default: false
  },
  primaryKey: {
    type: String,
    default: 'id'
  },
  showSummary: {
    type: Boolean,
    default: false
  },
  summaryMethod: Function,
})
const _data = defineModel({default: []})
const hook = commonHook({
  baseUrl: props.baseUrl,
  isPage: !props.isSub && props.isPage,
  conditions: props.conditions,
  isSub: props.isSub,
  simpleTitle: props.simpleTitle,
  _data,
  columns,
})

const {
  //后端api
  commonQueryFn, getById, empty, list, page, save, update, saveOrUpdate, removeByIds, importTemplate, importData, downBinary,
  //vue变量或js变量
  queryParams, selection, getQueryOptions, orderBy, isPage, pagination, emptyData, _this, loading, actionsFormVisible,
  //业务方法
  search, searchEmpty, handleSelectionChange, handleAdd, handleEdit, handleDelete, handleImportTemplate, handleImportData, computeColumnWidth,
} = hook

onMounted(async () => {
  formatParams()
  await search()
  await searchEmpty()
})

const topActions = computed(() => {
  return props.actions ? props.actions.filter(action => action.location !== 'row') : []
})

const rowActions = computed(() => {
  return props.actions ? props.actions.filter(action => action.location === 'row') : []
})

const colSetting = ref({
  visible: false,
})

function formatParams() {
  formatShowParams(columns.value)
}

function formatShowParams(_columns) {
  if (!_columns || !_columns.length) return
  _columns.forEach(column => column.show = column.hasOwnProperty('show') ? column.show : true)
  if (_columns.children) {
    _columns.children.forEach(child => formatShowParams(child))
  }
}

const searchClose = ref(true)

const contentHeight = computed(() => {
  const searchRowCount = (props.querySearch && props.querySearch.rowCount) || 2
  const eachRowHeight = 50
  const topActionHeight = 50
  const pageHeight = 40
  const searchOptionsSize = (props.querySearch && props.querySearch.options && props.querySearch.options.length) || 0
  let searchHeight = 0
  if (searchOptionsSize > 0) {
    if (searchClose.value) {
      searchHeight = eachRowHeight
    } else {
      searchHeight = (searchOptionsSize <= searchRowCount ? 1 : Math.ceil((searchOptionsSize + 1) / (searchRowCount + 1))) * eachRowHeight
    }
  }
  return `height: calc(100% - ${searchHeight + topActionHeight + pageHeight}px)`
})
</script>

<style lang="scss">
</style>
